package cn.xenosp.server.common.aop;

import cn.dev33.satoken.stp.StpUtil;
import cn.xenosp.server.common.Constant;
import cn.xenosp.server.common.Result;
import cn.xenosp.server.common.cache.Cache;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * 项目名： service-web
 * 包路径： cn.xenosp.server.common.aop
 * 作者：   TongHui
 * 创建时间: 2025-01-10 13:22
 * 描述: 页面访问权限控制
 * 版本: 1.0
 */
@Aspect
@Component
public class PermissionAspect {

    private static final Logger logger = LoggerFactory.getLogger(PermissionAspect.class);

    @Autowired
    Cache redisCache;

    @Around("execution(* cn.xenosp.server.web.controller.PageController.webPageLoader(..))")
    public Object checkPermission(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        if (args.length > 0 && args[0] instanceof Map) {
            Map<String, String> map = (Map<String, String>) args[0];
            String tokenValue = StpUtil.getTokenValue();
            Map<String, Object> cacheMap = (Map<String, Object>) redisCache.get(Constant.TOKEN + "_" + tokenValue);
            if (cacheMap == null) {
                logger.warn("Cache map is null for token: {}", tokenValue);
                return "login.html";
            }
            List<Map<String, Object>> response = (List<Map<String, Object>>) cacheMap.get("menu");
            if (response == null) {
                logger.warn("Menu list is null for token: {}", tokenValue);
                return "error/4xx.html";
            }
            String targetUrl = map.get("pageUrl");
            if (isPermission(response, targetUrl)) {
                return joinPoint.proceed();
            } else {
                logger.warn("Permission denied for URL: {} and token: {}", targetUrl, tokenValue);
                return "error/4xx.html";
            }
        }
        return joinPoint.proceed();
    }


    /**
     * 递归检查用户是否有权限访问目标URL
     *
     * @param response  菜单列表
     * @param targetUrl 目标URL
     * @return 如果有权限返回true，否则返回false
     */
    private boolean isPermission(List<Map<String, Object>> response, String targetUrl) {
        for (Map<String, Object> map : response) {
            String url = (String) map.get("url");
            if (url != null && targetUrl.endsWith(url)) {
                return true;
            }
            List<Map<String, Object>> menus = (List<Map<String, Object>>) map.get("list");
            if (menus != null && !menus.isEmpty()) {
                if (isPermission(menus, targetUrl)) {
                    return true;
                }
            }
        }
        return false;
    }
}
